Skip to main content

libobs_simple\sources\linux\sources\pipewire/
mod.rs

1mod camera;
2pub use camera::*;
3
4mod desktop;
5pub use desktop::*;
6
7mod screen;
8pub use screen::*;
9
10mod window;
11pub use window::*;
12
13mod restore_updater;
14pub use restore_updater::*;
15
16use libobs_wrapper::{
17    data::{object::ObsObjectTrait, ObsDataGetters},
18    run_with_obs,
19    sources::ObsSourceRef,
20    utils::ObsError,
21};
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24/// PipeWire source type
25pub enum ObsPipeWireSourceType {
26    /// Screen capture via desktop portal
27    DesktopCapture,
28    WindowCapture,
29    ScreenCapture,
30    /// Camera capture via camera portal
31    CameraCapture,
32}
33
34#[derive(Debug, Clone)]
35/// General PipeWire source reference wrapper, which has a restore_token
36pub struct ObsPipeWireSourceRef {
37    source: ObsSourceRef,
38    source_type: ObsPipeWireSourceType,
39}
40
41libobs_wrapper::forward_obs_object_impl!(ObsPipeWireSourceRef, source, *mut libobs::obs_source);
42libobs_wrapper::forward_obs_source_impl!(ObsPipeWireSourceRef, source);
43
44impl ObsPipeWireSourceRef {
45    /// Creates a new `ObsPipeWireSourceRef` from an `ObsSourceRef`.
46    pub fn new(source: ObsSourceRef, source_type: ObsPipeWireSourceType) -> Result<Self, ObsError> {
47        Ok(Self {
48            source,
49            source_type,
50        })
51    }
52
53    /// Gets the restore token used for reconnecting to previous sessions for `pipewire-desktop-capture-source` and `pipewire-window-capture-source` sources.
54    ///
55    /// As of right now, there is no callback or signal to notify when the token has been set, you have to call this method to get the restore token.
56    ///
57    /// The restore token will most probably be of `Some(String)` after the user has selected a screen or window to capture.
58    pub fn get_restore_token(&self) -> Result<Option<String>, ObsError> {
59        let source_ptr = self.as_ptr();
60        run_with_obs!(self.runtime(), (source_ptr), move || unsafe {
61            // Safety: Safe because we are using a smart pointer
62            libobs::obs_source_save(source_ptr.get_ptr());
63        })?;
64
65        let settings = self.settings()?;
66        let token = settings.get_string("RestoreToken")?;
67        Ok(token)
68    }
69
70    pub fn create_updater<'a>(
71        &'a mut self,
72    ) -> Result<ObsPipeWireGeneralUpdater<'a>, libobs_wrapper::utils::ObsError> {
73        use libobs_wrapper::data::object::ObsObjectTrait;
74        use libobs_wrapper::data::ObsObjectUpdater;
75        ObsPipeWireGeneralUpdater::create_update(self.runtime().clone(), self)
76    }
77
78    pub fn get_source_type(&self) -> ObsPipeWireSourceType {
79        self.source_type
80    }
81}
82
83macro_rules! impl_pipewire_source_builder {
84    ($struct_name: ident, $source_type: expr) => {
85        impl libobs_wrapper::sources::ObsSourceBuilder for $struct_name {
86            type T = crate::sources::linux::pipewire::ObsPipeWireSourceRef;
87
88            fn build(self) -> Result<Self::T, libobs_wrapper::utils::ObsError>
89            where
90                Self: Sized,
91            {
92                use libobs_wrapper::data::ObsObjectBuilder;
93                let runtime = self.runtime.clone();
94                let info = self.object_build()?;
95
96                let source = libobs_wrapper::sources::ObsSourceRef::new_from_info(info, runtime)?;
97
98                crate::sources::linux::pipewire::ObsPipeWireSourceRef::new(source, $source_type)
99            }
100        }
101    };
102}
103
104pub(crate) use impl_pipewire_source_builder;